﻿using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using yzrilyzr.util;

namespace FAQ_UI
{
	public class ImageCropView : Panel
	{
		private BitmapImage image;
		private double widthHeightRatio;
		private double x, y, w;
		private Typeface typeface;
		private int downType = -1;
		private Point downPoint = new Point();
		private double lastX, lastY, lastW;

		public ImageCropView()
		{
			typeface = FAQUtil.getIconFont();
		}

		private double getBitmapScale()
		{
			double scale = 1;
			double sc1 = RenderSize.Width / image.PixelWidth;
			scale = sc1;
			if (image.PixelHeight * scale > RenderSize.Height)
			{
				double sc2 = RenderSize.Height / image.PixelHeight;
				scale = sc2;
			}
			return scale;
		}

		private Rect getCropRectDraw()
		{
			double scale = getBitmapScale();
			double rW = image.PixelWidth * scale;
			double rH = image.PixelHeight * scale;
			double bx = RenderSize.Width / 2 - rW / 2;
			double by = RenderSize.Height / 2 - rH / 2;
			return new Rect(bx + x * scale, by + y * scale, w * scale, w * scale / widthHeightRatio);
		}

		private Rect getBitmapRectDraw()
		{
			double scale = getBitmapScale();
			double rW = image.PixelWidth * scale;
			double rH = image.PixelHeight * scale;
			double bx = RenderSize.Width / 2 - rW / 2;
			double by = RenderSize.Height / 2 - rH / 2;
			return new Rect(bx, by, rW, rH);
		}

		protected override void OnRender(DrawingContext dc)
		{
			base.OnRender(dc);
			if (image == null) return;
			dc.DrawImage(image, getBitmapRectDraw());
			Pen pen = new Pen(new SolidColorBrush(Color.FromRgb(255, 255, 255)), 3);
			Rect r = getCropRectDraw();
			dc.DrawRectangle(null, pen, r);
			double size = 20;
			double size2 = 15;
			Brush IconBrush1 = new SolidColorBrush(Color.FromRgb(255, 255, 255));
			Brush IconBrush = new SolidColorBrush(Color.FromRgb(0, 0, 0));
			FormattedText t = new FormattedText("\ue89f", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, size2, IconBrush, 96);
			dc.DrawEllipse(IconBrush1, null, new Point(r.X, r.Y), size / 2, size / 2);
			dc.DrawText(t, new Point(r.X - size2 / 2, r.Y - size2 / 2));
			t = new FormattedText("\ue56b", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, size2, IconBrush, 96);
			dc.DrawEllipse(IconBrush1, null, new Point(r.Right, r.Bottom), size / 2, size / 2);
			dc.DrawText(t, new Point(r.Right - size2 / 2, r.Bottom - size2 / 2));
		}

		protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
		{
			base.OnRenderSizeChanged(sizeInfo);
			InvalidateVisual();
		}

		internal void setImage(BitmapImage b)
		{
			this.image = b;
			this.w = b.PixelWidth / 3;
			this.x = b.PixelWidth / 2 - w / 2;
			double h = w / widthHeightRatio;
			this.y = b.PixelHeight / 2 - h / 2;
			InvalidateVisual();
		}

		public Int32Rect getCropResult()
		{
			int mx = Util.clamp((int)x, 0, image.PixelWidth);
			int my = Util.clamp((int)y, 0, image.PixelHeight);
			int mw = Util.clamp((int)w, 0, image.PixelWidth - mx);
			int mh = Util.clamp((int)(w / widthHeightRatio), 0, image.PixelHeight - my);
			return new Int32Rect(mx, my, mw, mh);
		}

		protected override void OnMouseUp(MouseButtonEventArgs e)
		{
			e.Handled = true;
			downType = -1;
		}

		protected override void OnMouseDown(MouseButtonEventArgs e)
		{
			e.Handled = true;
			downPoint = e.GetPosition(this);
			lastX = x;
			lastY = y;
			lastW = w;
			Rect r = getCropRectDraw();
			double size = 20;
			if (Math.Pow(downPoint.X - r.X, 2) + Math.Pow(downPoint.Y - r.Y, 2) < size * size)
			{
				downType = 0;
			}
			else if (Math.Pow(downPoint.X - r.Right, 2) + Math.Pow(downPoint.Y - r.Bottom, 2) < size * size)
			{
				downType = 1;
			}
			else downType = -1;
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			e.Handled = true;
			if (downType == 0)
			{
				Point pos = e.GetPosition(this);
				double scale = getBitmapScale();
				Rect br = getBitmapRectDraw();
				this.x = lastX + (pos.X - downPoint.X) / scale;
				this.y = lastY + (pos.Y - downPoint.Y) / scale;
				InvalidateVisual();
			}
			else if (downType == 1)
			{
				Point pos = e.GetPosition(this);
				double scale = getBitmapScale();
				Rect br = getBitmapRectDraw();
				this.w = lastW + (pos.X - downPoint.X) / scale;
				InvalidateVisual();
			}
		}

		internal void setWidthHeightRatio(double widthHeightRatio)
		{
			this.widthHeightRatio = widthHeightRatio;
			InvalidateVisual();
		}

		internal BitmapImage getImage()
		{
			return image;
		}
	}
}